package de.homelabs.spring.freemarker.views;

import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.BeansException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;

import de.homelabs.spring.freemarker.domain.TemplateContainer;
import de.homelabs.spring.freemarker.service.HLFreeMarkerTemplateManager;
import freemarker.ext.jsp.TaglibFactory;
import freemarker.ext.servlet.FreemarkerServlet;
import freemarker.ext.servlet.HttpRequestHashModel;
import freemarker.ext.servlet.HttpRequestParametersHashModel;
import freemarker.ext.servlet.HttpSessionHashModel;
import freemarker.ext.servlet.ServletContextHashModel;
import freemarker.template.SimpleHash;
import freemarker.template.utility.StringUtil;

/**
 * active class
 * vielleicht brauch ich die gar nicht wenn ich die Templates aus der DB hole mit TemplateLoder
 * trotzdem behalten, wer weiss wofuer :-)
 * http://nurkiewicz.blogspot.com/2010/01/writing-custom-freemarker-template.html
 * 
 * @author D.Mueller
 * 
 */
@Component
@Scope("session")
public class HLFreeMarkerViewWithTemplateManager extends FreeMarkerView {

	/* vars */
	private TaglibFactory taglibFactory;

	private ServletContextHashModel servletContextHashModel;

	private String templateKey = "";

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#
	 * initApplicationContext() TODO: check if need or unneeded
	 */
	@Override
	protected void initApplicationContext() throws BeansException {
		if (this.getUrl() != null) {
			// save the template key for future user
			// url contains template key for template manager, replace extension
			// do not use suffix with view resolver
			templateKey = StringUtil.replace(this.getUrl(), ".ftl", "", true,false);

			// set existing default to prevent FreeMarkerView.checkTemplate()
			// from failing :-)
			TemplateContainer tc = HLFreeMarkerTemplateManager.getInstance()
					.getTemplateContainerByTemplateKey("default");

			// set the default template
			this.setUrl(tc.getTemplateUrl());
		}
		// init super
		super.initApplicationContext();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#
	 * renderMergedTemplateModel(java.util.Map,
	 * javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void renderMergedTemplateModel(@SuppressWarnings("rawtypes") Map model,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		exposeHelpers(model, request);
		doRender(model, request, response);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.web.servlet.view.freemarker.FreeMarkerView#doRender
	 * (java.util.Map, javax.servlet.http.HttpServletRequest,
	 * javax.servlet.http.HttpServletResponse) TODO: must be more dynamic,
	 * declaration from database?
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	protected void doRender(Map model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		// the page show is defined by the parameter 'url' which can be
		// overridden
		// setUrl(TemplateToView)
		// default is set with the parameter 'viewName' from 'ModelAndView'

		// Grab the locale-specific version of the template.
		Locale locale = RequestContextUtils.getLocale(request);

		// Expose model to JSP tags (as request attributes).
		exposeModelAsRequestAttributes(model, request);

		// Expose all standard FreeMarker hash models.
		model.put(FreemarkerServlet.KEY_JSP_TAGLIBS, this.taglibFactory);
		model.put(FreemarkerServlet.KEY_APPLICATION,
				this.servletContextHashModel);
		model.put(FreemarkerServlet.KEY_SESSION,
				buildSessionModel(request, response));
		model.put(FreemarkerServlet.KEY_REQUEST, new HttpRequestHashModel(
				request, response, getObjectWrapper()));
		model.put(FreemarkerServlet.KEY_REQUEST_PARAMETERS,
				new HttpRequestParametersHashModel(request));

		if (logger.isDebugEnabled()) {
			logger.debug("Rendering FreeMarker template [" + getUrl()
					+ "] in FreeMarkerView '" + getBeanName() + "'");
		}

		/*************************************************
		 * START Homelabs service here (TemplateManager) *
		 *************************************************/
		if (!this.templateKey.equalsIgnoreCase("default")) {
			// get mainmenu Template
//			String mainMenu = FreeMarkerTemplateUtils
//					.processTemplateIntoString(
//							getTemplate(
//									"de/homelabs/bookstore/web/templates/mainmenu.ftl",
//									locale), model); // expects menuentries
//			// add the parsed menu to model
//			model.put("mainMenu", mainMenu);

			// create diffrent views
//			String header = "";
//			String content = "";
//			String footer = "";
//			String category = "";

//			category = FreeMarkerTemplateUtils
//					.processTemplateIntoString(
//							getTemplate(
//									"de/homelabs/bookstore/web/templates/categories.ftl",
//									locale), model); // expects categorieslist
//			model.put("categories", category);
//			header = FreeMarkerTemplateUtils.processTemplateIntoString(
//					getTemplate(
//							"de/homelabs/bookstore/web/templates/header.ftl",
//							locale), model); // expects mainMenu
//			model.put("header", header);
//			content = FreeMarkerTemplateUtils.processTemplateIntoString(
//					getTemplate("de/homelabs/bookstore/web/templates/main.ftl",
//							locale), model); // expects newslist, categorieslist
//			model.put("content", content);
//			footer = FreeMarkerTemplateUtils.processTemplateIntoString(
//					getTemplate(
//							"de/homelabs/bookstore/web/templates/footer.ftl",
//							locale), model); // expects
//			model.put("footer", footer);

			// set the url to the real template
			if (templateKey.equalsIgnoreCase("testt")) {
				setUrl("de/homelabs/bookstore/web/templates/test2.ftl");
			} else {
				setUrl("de/homelabs/bookstore/web/templates/test.ftl");
			}
		} else {
			// TemplateContainer tc =
			// HLFreeMarkerTemplateManager.getInstance().getDefaultTemplateContainer();
			TemplateContainer tc = HLFreeMarkerTemplateManager.getInstance()
					.getTemplateContainerByTemplateKey("default");

			// set the default template
			this.setUrl(tc.getTemplateUrl());
		}

		/*************************************************
		 * END Homelabs service here (TemplateManager) *
		 *************************************************/

		// process final template
		processTemplate(getTemplate(locale), new SimpleHash(model), response);
	}

	/**
	 * Build a FreeMarker {@link HttpSessionHashModel} for the given request,
	 * detecting whether a session already exists and reacting accordingly.
	 * 
	 * @param request
	 *            current HTTP request
	 * @param response
	 *            current servlet response
	 * @return the FreeMarker HttpSessionHashModel
	 */
	private HttpSessionHashModel buildSessionModel(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			return new HttpSessionHashModel(session, getObjectWrapper());
		} else {
			return new HttpSessionHashModel(null, request, response,
					getObjectWrapper());
		}
	}

}
